#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define PORT 4433
#define SERVER_IP "127.0.0.1"

int setup_ssl_CTX_client(SSL_CTX** ctx) {
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();
    *ctx = SSL_CTX_new(TLS_client_method());
    if (*ctx == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    return 0;
}

int main() {
    int server;
    SSL_CTX* ctx;
    SSL* ssl;
    char buf[1024];
    const char* message = "Hello from client";

    setup_ssl_CTX_client(&ctx);

    server = socket(AF_INET, SOCK_STREAM, 0);
    if (server < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in serv_addr;
    memset(&serv_addr, '0', sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr);

    if (connect(server, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection failed");
        exit(EXIT_FAILURE);
    }

    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    if (SSL_connect(ssl) == -1) {
        ERR_print_errors_fp(stderr);
    } else {
        SSL_write(ssl, message, strlen(message));
        printf("Message sent\n");

        int bytes = SSL_read(ssl, buf, sizeof(buf));
        if (bytes > 0) {
            buf[bytes] = '\0';
            printf("Server response: \"%s\"\n", buf);
        }
    }

    close(server);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}